package hook

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	jsoniter "github.com/json-iterator/go"
)

var (
	ErrConfNot = errors.New("未找到项目配置。")
	ErrToken	= errors.New("签名不匹配。")

	configs *Configs
	email *Email
)

// 配置
type Configs struct {
	HookGroup map[string]map[string]*ProjectConf	`json:"hook_group"`
	EmailSender *EmailConf							`json:"email_sender"`
}

// 响应
type Result struct {
	Code    int
	Message string
	Data interface{}
}

// 初始化钩子
func InitHook(conf []byte)(err error){
	configs = &Configs{}
	// 解析配置
	if err = jsoniter.Unmarshal(conf, &configs); err != nil{
		return fmt.Errorf("hook 配置解析错误:%w", err)
	}
	// 增加默认配置(钩子启动的时候，会发送一条测试推送)
	for k,_ := range configs.HookGroup{
		configs.HookGroup[k]["oschina/git-osc"] = &ProjectConf{
			Token: "false", // 表示不验证令牌
			Event: Events{},
		}
	}



	// 载入邮箱配置
	email = NewEmailCli(configs.EmailSender)
	return nil
}


// git 钩子接收处理
func GiteeHook(w http.ResponseWriter, r *http.Request) {
	re := Result{Message: "ok"}
	//var hook Hook
	//var err error
	defer func() {
		b, _ := jsoniter.Marshal(re)
		_, _ = w.Write(b)
	}()
	if r.Method != http.MethodPost {
		re.Code, re.Message = 1, "错误的请求类型"
		return
	}
	group := r.URL.Query().Get("g")
	if _, ok := configs.HookGroup[group]; !ok{
		re.Code, re.Message = 1, "请正确传递组编号 http://host:port?g=*?*"
		return
	}

	// 确定请求类型，然后载入对应的结构体。
	bodyByte, _ := ioutil.ReadAll(r.Body)
	// 确定事件类型
	switch r.Header.Get("X-Gitee-Event") {
	case "Push Hook":
		if push, err := NewPush(group, bodyByte); err != nil {
			re.Code, re.Message = 1, err.Error()
		}else if err = email.PushEventSend(push); err != nil {
			log.Println("邮件发送错误:", err.Error())
			re.Code, re.Message = 2, "业务执行成功:"+ err.Error()
		}else {
			re.Data = map[string]string{
				"sell": string(push.GetSellResult()),
			}
		}
	case "Note Hook":
		re.Code, re.Message = 1, "WebHook 暂只受理 push 事件."
	case "lssue":
		re.Code, re.Message = 1, "WebHook 暂只受理 push 事件."
	case "Pull":
		re.Code, re.Message = 1, "WebHook 暂只受理 push 事件."
	default:
		re.Code, re.Message = 1, "未知的事件"
		return
	}

	// 推送邮件
	//fmt.Println(hook)
	//email.DialAndSend()

}

// 邮件发送
func SendEmail(){

}